#include "uhm/common.hxx"
#include "uhm/util.hxx"
#include "uhm/mat.hxx"

#include "uhm/mat/linal.hxx"

#define N 1

using namespace uhm;

typedef ID_Node_H_<N>             Id_Nd;

int main (int argc, char **argv) {

  initialize(argc, argv);

  Int_ dof;
  get_option_int("-dof", "Dof per node", __FILE__, 1, dof);

  Int_ blk = 2, n_nodes = 5, dim = n_nodes*dof;
  
  Mat_Linal_ A(Mat_Base_::DOUBLE, dim, dim), B(A);
  A.create_flat_without_buffer();
  A.create_flat_buffer();
  A.create_hier(blk, blk);

  B.create_flat_without_buffer();
  B.create_flat_buffer();
  B.create_hier(blk, blk);

  random_matrix(A);

  Id_Nd nd;
  Map_<Id_Nd> MA(n_nodes), MB(n_nodes);

  MA.push_begin();

  nd.set_id(0, 0); nd.set_dof(dof); MA.push(nd);
  nd.set_id(0, 1); nd.set_dof(dof); MA.push(nd);
  nd.set_id(0, 2); nd.set_dof(dof); MA.push(nd);
  nd.set_id(0, 3); nd.set_dof(dof); MA.push(nd);
  nd.set_id(0, 4); nd.set_dof(dof); MA.push(nd);

  MA.push_end();

  MB.push_begin();

  nd.set_id(0, 4); nd.set_dof(dof); MB.push(nd);
  nd.set_id(0, 3); nd.set_dof(dof); MB.push(nd);
  nd.set_id(0, 5); nd.set_dof(dof); MB.push(nd);
  nd.set_id(0, 1); nd.set_dof(dof); MB.push(nd);
  nd.set_id(0, 0); nd.set_dof(dof); MB.push(nd);

  MB.push_end();
  
  time_begin();

  time_in("map:: Relating Map");
  Mapper_<Id_Nd> M(&MA, &MB);
  M.relate();
  time_out();

  if (get_verbose())
    std::cout << "Original = \n" << A << B << M ;

  time_in("map:: Copying with Mapper");
  copy<Id_Nd>(M, M, A, B);
  time_out();

  time_end();

  if (get_verbose())
    std::cout << "Mapping done = \n" << A << B << M ;

  A.free_all();
  B.free_all();

  finalize();

  return true;
}


